﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using Cms.Data;
using Cms.Domain;
using Cms.Domain.Comparers;
using Cms.Domain.RepositoryInterfaces;
using Cms.Utilities;
using Cms.Web.Framework.Extensions;
using Cms.Web.Framework.Plugins.Attributes;
using iLib.Web.UI;
using iLib.Web.UI.WebControls;
using SortDirection = Cms.Domain.SortDirection;

namespace Cms.Web.Framework.Plugins
{
    public class ImageGallery : BaseTemplatedPlugin
    {
        // Property fields
        private int _categoryID;
        private int _numericID;
        private int _previewMaxHeight;
        private int _previewMaxWidth;
        private SortDirection _sortDirection;
        private MediaSortMode _sortMode;
        private bool _usePreviews;
        private Image imgCurrent;
        private iRepeater rpImages;

        public ImageGallery()
        {
            _usePreviews = true;
        }

        [Enumeration("Categories", true)]
        public int CategoryID
        {
            get { return _categoryID; }
            set { _categoryID = value; }
        }

        [Enumeration("MediaSortMode", true)]
        public MediaSortMode SortMode
        {
            get { return _sortMode; }
            set { _sortMode = value; }
        }

        [Enumeration("SortDirections", true)]
        public SortDirection SortDirection
        {
            get { return _sortDirection; }
            set { _sortDirection = value; }
        }
        
        public bool UsePreviews
        {
            get { return _usePreviews; }
            set { _usePreviews = value; }
        }
        
        public int PreviewMaxWidth
        {
            get { return _previewMaxWidth; }
            set { _previewMaxWidth = value; }
        }
        
        public int PreviewMaxHeight
        {
            get { return _previewMaxHeight; }
            set { _previewMaxHeight = value; }
        }

        public virtual void OnItemDataBound(object sender, RepeaterItemEventArgs e)
        {
        }

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            IEnumerable<ImageGallery> existingImageGalleries = Page.AllControls().OfType<ImageGallery>();
            _numericID = existingImageGalleries.Count();
        }
        
        protected override void CreateChildControls()
        {
            try
            {
                base.CreateChildControls();
                IList<MediaFile> images = GetImages();
                imgCurrent = (Image)FindControl("imgCurrent");
                if (imgCurrent != null)
                {
                    imgCurrent.ImageUrl = images[0].GetVirtualPath();
                    imgCurrent.Attributes.Add("galleryID", _numericID.ToString());
                }
                if (_usePreviews)
                {
                    rpImages = (iRepeater)FindControl("rpImages");
                    rpImages.ItemDataBound += rpImages_ItemDataBound;
                    rpImages.DataSource = images;
                    rpImages.DataBind();
                }
                var hlPrev = (HtmlAnchor)FindControl("hlPrev");
                string hlPrevClientID = string.Empty;
                if (hlPrev != null)
                {
                    hlPrev.HRef = "javascript:cms.Plugins.ImageGallery.ShowPrevious(" + _numericID + ");";
                    hlPrevClientID = hlPrev.ClientID;
                }
                string hlNextClientID = string.Empty;
                var hlNext = (HtmlAnchor)FindControl("hlNext");
                if (hlNext != null)
                {
                    hlNext.HRef = "javascript:cms.Plugins.ImageGallery.ShowNext(" + _numericID + ");";
                    hlNextClientID = hlNext.ClientID;
                }
                if (imgCurrent != null)
                {
                    Page.AddHeaderScriptInclude(ConfigurationManager.AppSettings["jQueryPath"]);
                    Page.AddHeaderScriptInclude("Admin/js/CmsLib.js");
                    Page.AddHeaderScriptInclude("Admin/js/Plugins/ImageGallery.js");
                    string script = "cms.Plugins.ImageGallery.Init(" + _numericID + ", " +
                                    "'" + imgCurrent.ClientID + "', " +
                                    "'" + hlPrevClientID + "', " +
                                    "'" + hlNextClientID + "', " + "[";
                    string files = string.Empty;
                    foreach (MediaFile img in images)
                    {
                        if (files.Length > 0)
                            files += ", ";
                        files += "'" + img.GetVirtualPath().Replace("'", "\\'") + "'";
                    }
                    script += files + "], 100);";
                    ClientScriptProxy.Current.RegisterStartupScript(
                        Parent, 
                        Page.GetType(),
                        "Cms.Web.Framework.Plugins.ImageGallery" + _numericID, 
                        script, 
                        true);
                }
            }
            catch (Exception ex)
            {
                Logging.LogError("ImageGallery", ex);
                Controls.Clear();
            }
        }

        protected void rpImages_ItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem)
                return;
            var file = (MediaFile)e.Item.DataItem;
            var imgPreview = (Image)e.Item.FindControl("imgPreview");
            var litTitle = (Literal)e.Item.FindControl("litTitle");
            var litDescription = (Literal)e.Item.FindControl("litDescription");
            imgPreview.ImageUrl = Url.VirtualPath + "Thumbnail.aspx?file=" + Server.UrlEncode(file.GetVirtualPath()) +
                                  "&width=" + _previewMaxWidth + "&height=" + _previewMaxHeight;
            if (litTitle != null && file.LocalizedProperties.ContainsKey(RequestDetails.Locale.ID))
                litTitle.Text = file.LocalizedProperties[RequestDetails.Locale.ID].Title;
            if (litDescription != null && file.LocalizedProperties.ContainsKey(RequestDetails.Locale.ID))
                litDescription.Text = file.LocalizedProperties[RequestDetails.Locale.ID].Description;
            ((ImageGallery)TemplateInstance).OnItemDataBound(sender, e);
            if (imgCurrent == null)
                return;
            imgPreview.Attributes.Add(
                "onclick",
                "cms.Plugins.ImageGallery.UpdateCurrent(" + _numericID + ", '" + file.GetVirtualPath().Replace("'", "\\'") + "');");
        }

        public IList<MediaFile> GetImages()
        {
            var files = new List<MediaFile>();
            ICategoryRepository categoryRepository = new CategoryRepository();
            Category category = categoryRepository.GetCategory(_categoryID);
            if (category == null)
            {
                return files;
            }
            foreach (MediaFile file in category.MediaFiles)
            {
                string extension = file.Extension.ToLower();
                if (extension == "png" || extension == "jpg" || extension == "gif")
                {
                    files.Add(file);
                }
            }
            foreach (MediaFolder folder in category.MediaFolders)
            {
                foreach (MediaFile file in folder.GetAllFiles())
                {
                    if (files.Contains(file))
                    {
                        continue;
                    }
                    string extension = file.Extension.ToLower();
                    if (extension == "png" || extension == "jpg" || extension == "gif")
                    {
                        files.Add(file);
                    }
                }
            }
            files.Sort(new MediaFileComparer(_sortDirection, _sortMode));
            return files;
        }
    }
}